/*============组合继承========== */
//又叫伪经典继承，是指将原型链和借用构造函数技术组合在一块的一种继承方式。
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function () {
    console.log(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.log(instance1.colors); //red,blue,green,black
instance1.sayName(); //Nicholas
instance1.sayAge(); //29

var instance2 = new SubType("Greg", 27);
console.log(instance2.colors); //red,blue,green
instance2.sayName(); //Greg
instance2.sayAge(); //27

/*============原型式继承========== */
//可以在不必预先定义构造函数的情况下实现继承，其本质是执行对给定对象的浅复制。而复制得到的副本还可以得到进一步的改造。
function object(o) {
    function F() {
    };
    F.prototype = o;
    return new F;
}

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"],
    say:function(){
        console.log("hello "+this.name);
    }
};

var antherPerson1 = object(person);
antherPerson1.name = "Greg";
antherPerson1.friends.push("Rob");


var antherPerson = object(person);
antherPerson.name = "Linda";
antherPerson.friends.push("Barbie");

antherPerson1.say();
antherPerson.say();

console.log(person.friends); //Shelby,Court,Van,Rob,Barbie
console.log(person.name);
console.log(antherPerson1.name);
console.log(antherPerson.name);
/*============寄生式继承========== */
//与原型式继承非常相似，也是基于某个对象或某些信息创建一个对象，然后增强对象，最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题，可以将这个模式与组合继承一起使用。
function object(o) {
    function F() {
    };
    F.prototype = o;
    return new F;
}
function createAnother(original) {
    var clone = object(original);
    clone.sayHi = function () {
        console.log("Hi");
    };
    return clone;
}

var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};

var anotherPerson = createAnother(person);
anotherPerson.sayHi();
/*============寄生组合式继承========== */
//集寄生式继承和组合继承的优点与一身，是实现基本类型继承的最有效方式。
//继承原型
function extend(subType, superType) {
    function F() {
    };
    F.prototype = superType.prototype;

    var prototype = new F;
    prototype.constructor = subType;
    subType.prototype = prototype;
}

//超类方法
function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
    return this.name;
}

//子类方法
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}

//继承超类的原型
extend(SubType, SuperType);

//子类方法
SubType.prototype.sayAge = function () {
    return this.age;
}

var instance1 = new SubType("Shelby");
var instance2 = new SubType("Court", 28);

instance1.colors.push('black');

console.log(instance1.colors); //red,blue,green,black
console.log(instance2.colors); //red,blue,green

console.log(instance1 instanceof SubType); //true
console.log(instance1 instanceof SuperType); //true